/**
 * This file is part of 1genia trampoline
 * Copyright (C) 2007 1genia (contact@1genia.com)
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; version 3 of the License. 
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; see the file COPYING.TXT.  If not,
 * write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA 02110-1301, USA. 
 **/
package com.genia.toolbox.portlet.editor.gui.dialog.panel;

import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;

import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JTextArea;
import javax.swing.ListCellRenderer;

import com.genia.toolbox.basics.editor.gui.dialog.panel.AbstractSettingsPanel;
import com.genia.toolbox.portlet.editor.gui.PortletEditorGUI;
import com.genia.toolbox.portlet.editor.model.bean.PortletInitialSettings;
import com.genia.toolbox.portlet.editor.model.portlet.PortletType;
import com.genia.toolbox.web.portlet.description.ContainerPortletDescription;
import com.genia.toolbox.web.portlet.description.PortletDescription;
import com.genia.toolbox.web.portlet.description.SimplePortletDescription;

/**
 * The portlet selection panel. Used to create a portlet or to select a
 * sub-portlet.
 */
@SuppressWarnings("serial")
public class PortletSelectionPanel
    extends AbstractSettingsPanel<PortletEditorGUI, PortletInitialSettings>
{

  /**
   * The label of the portlet type.
   */
  private JLabel labelType = null;

  /**
   * The selection of the portlet type.
   */
  private JComboBox comboType = null;

  /**
   * The label of the portlet.
   */
  private JLabel labelPortlet = null;

  /**
   * The selection of the portlet.
   */
  private JComboBox comboPortlet = null;

  /**
   * The label of the portlet description.
   */
  private JLabel labelDescription = null;

  /**
   * The selection of the portlet description.
   */
  private JTextArea areaDescription = null;

  /**
   * Whether the panel is used for templating, which means we will remove the
   * hole portlet.
   */
  private boolean canBeForTemplating = true;



  /**
   * Constructor.
   * 
   * @param gui
   *          The gui.
   * @param canBeForTemplating
   *          Whether the panel will be used for templating.
   */
  public PortletSelectionPanel(PortletEditorGUI gui, boolean canBeForTemplating)
  {
    super(gui);
    this.canBeForTemplating = canBeForTemplating;

    GridBagLayout layout = new GridBagLayout();
    GridBagConstraints constraints = new GridBagConstraints();
    this.setLayout(layout);

    this.labelType = new JLabel(this.getGui().getController().notifyTranslation("com.genia.toolbox.portlet.editor.gui.dialog.PortletSelectorDialog.label.type"));
    constraints.gridx = 1;
    constraints.gridy = 1;
    constraints.gridwidth = 1;
    constraints.gridheight = 1;
    constraints.weightx = 0;
    constraints.weighty = 0;
    constraints.fill = GridBagConstraints.HORIZONTAL;
    constraints.insets = new Insets(0, 0, 0, 0);
    this.add(this.labelType, constraints);

    PortletType[] type = PortletType.values();
    if (!this.canBeForTemplating) {
      type = new PortletType[5];
      type[0] = PortletType.Container;
      type[1] = PortletType.Dispatcher;
      type[2] = PortletType.Linked;
      type[3] = PortletType.Simple;
      type[4] = PortletType.Template;
    }
    this.comboType = new JComboBox(type);
    this.comboType.addActionListener(this);
    constraints.gridx = 2;
    constraints.gridy = 1;
    constraints.gridwidth = 1;
    constraints.gridheight = 1;
    constraints.weightx = 1;
    constraints.weighty = 0;
    constraints.fill = GridBagConstraints.HORIZONTAL;
    constraints.insets = new Insets(0, 5, 0, 0);
    this.add(this.comboType, constraints);

    this.labelPortlet = new JLabel(this.getGui().getController().notifyTranslation("com.genia.toolbox.portlet.editor.gui.dialog.PortletSelectorDialog.label.portlet"));
    constraints.gridx = 1;
    constraints.gridy = 2;
    constraints.gridwidth = 1;
    constraints.gridheight = 1;
    constraints.weightx = 0;
    constraints.weighty = 0;
    constraints.fill = GridBagConstraints.HORIZONTAL;
    constraints.insets = new Insets(5, 0, 0, 0);
    this.add(this.labelPortlet, constraints);

    this.comboPortlet = new JComboBox();
    this.comboPortlet.setRenderer(new ComboBoxRenderer());
    this.comboPortlet.addActionListener(this);
    constraints.gridx = 2;
    constraints.gridy = 2;
    constraints.gridwidth = 1;
    constraints.gridheight = 1;
    constraints.weightx = 1;
    constraints.weighty = 0;
    constraints.fill = GridBagConstraints.HORIZONTAL;
    constraints.insets = new Insets(5, 5, 0, 0);
    this.add(this.comboPortlet, constraints);

    this.labelDescription = new JLabel(this.getGui().getController().notifyTranslation("com.genia.toolbox.portlet.editor.gui.dialog.PortletSelectorDialog.label.description"));
    constraints.gridx = 1;
    constraints.gridy = 3;
    constraints.gridwidth = 1;
    constraints.gridheight = 1;
    constraints.weightx = 0;
    constraints.weighty = 0;
    constraints.fill = GridBagConstraints.HORIZONTAL;
    constraints.anchor = GridBagConstraints.NORTHWEST;
    constraints.insets = new Insets(5, 0, 0, 0);
    this.add(this.labelDescription, constraints);

    this.areaDescription = new JTextArea();
    this.areaDescription.setLineWrap(true);
    this.areaDescription.setWrapStyleWord(true);
    this.areaDescription.setFont(this.labelDescription.getFont());
    this.areaDescription.setEditable(false);
    constraints.gridx = 2;
    constraints.gridy = 3;
    constraints.gridwidth = 1;
    constraints.gridheight = 1;
    constraints.weightx = 1;
    constraints.weighty = 1;
    constraints.fill = GridBagConstraints.BOTH;
    constraints.insets = new Insets(5, 5, 0, 0);
    this.add(this.areaDescription, constraints);

    this.comboType.setSelectedItem(PortletType.Container);

  }



  /**
   * Create a model containing all the containers.
   * 
   * @return a model containing all the containers.
   */
  public ComboBoxModel getContainerModel()
  {
    ComboBoxModel model = new DefaultComboBoxModel(this.getGui().getController().notifyDisplayContainerPortletDescriptions().toArray());
    return model;
  }



  /**
   * Create a model containing all the simple portlets descriptions.
   * 
   * @return a model containing all the simple portlets descriptions.
   */
  public ComboBoxModel getSimpleModel()
  {
    ComboBoxModel model = new DefaultComboBoxModel(this.getGui().getController().notifyDisplaySimplePortletDescriptions().toArray());
    return model;
  }



  /**
   * Create a model containing all the templates.
   * 
   * @return a model containing all the templates.
   */
  public ComboBoxModel getTemplateModel()
  {
    ComboBoxModel model = new DefaultComboBoxModel(this.getGui().getController().notifyDisplayTemplatePortlets().toArray());
    return model;
  }



  /**
   * Handle the action events.
   * 
   * @param e
   *          the action event.
   */
  public void actionPerformed(ActionEvent e)
  {
    Object source = e.getSource();
    if (source.equals(this.comboType)) {
      PortletType type = (PortletType) this.comboType.getSelectedItem();
      if (type != null) {
        if (PortletType.Dispatcher.equals(type)) {
          this.comboPortlet.setSelectedItem(null);
          this.comboPortlet.setEnabled(false);
          this.areaDescription.setText(this.getGui().getController().notifyTranslation("com.genia.toolbox.portlet.editor.gui.dialog.PortletSelectorDialog.area.dispatcher"));
        }
        if (PortletType.Linked.equals(type)) {
          this.comboPortlet.setSelectedItem(null);
          this.comboPortlet.setEnabled(false);
          this.areaDescription.setText(this.getGui().getController().notifyTranslation("com.genia.toolbox.portlet.editor.gui.dialog.PortletSelectorDialog.area.linked"));
        }
        else if (PortletType.Container.equals(type)) {
          this.comboPortlet.setEnabled(true);
          this.comboPortlet.setModel(this.getContainerModel());
          if (this.comboPortlet.getModel().getSize() > 0) {
            this.comboPortlet.setSelectedIndex(0);
          }
        }
        else if (PortletType.Simple.equals(type)) {
          this.comboPortlet.setEnabled(true);
          this.comboPortlet.setModel(this.getSimpleModel());
          if (this.comboPortlet.getModel().getSize() > 0) {
            this.comboPortlet.setSelectedIndex(0);
          }
        }
        else if (PortletType.Hole.equals(type)) {
          this.comboPortlet.setSelectedItem(null);
          this.comboPortlet.setEnabled(false);
          this.areaDescription.setText(this.getGui().getController().notifyTranslation("com.genia.toolbox.portlet.editor.gui.dialog.PortletSelectorDialog.area.hole"));
        }
        else if (PortletType.Template.equals(type)) {
          this.comboPortlet.setEnabled(true);
          this.comboPortlet.setModel(this.getTemplateModel());
          if (this.comboPortlet.getModel().getSize() > 0) {
            this.comboPortlet.setSelectedIndex(0);
          }
          this.areaDescription.setText(this.getGui().getController().notifyTranslation("com.genia.toolbox.portlet.editor.gui.dialog.PortletSelectorDialog.area.template"));
        }
      }
    }
    else if (source.equals(this.comboPortlet)) {
      if (PortletType.Container.equals(this.comboType.getSelectedItem()) || PortletType.Simple.equals(this.comboType.getSelectedItem())) {
        PortletDescription description = (PortletDescription) this.comboPortlet.getSelectedItem();
        if (description != null) {
          this.areaDescription.setText(this.getGui().getController().notifyTranslation(description.getDescription()));
        }
      }
    }
  }

  /**
   * The combo box cell renderer.
   */
  public class ComboBoxRenderer
      extends JLabel
      implements ListCellRenderer
  {

    /**
     * Handle the display of the data.
     * 
     * @param list
     *          The list of data.
     * @param value
     *          The selected value.
     * @param index
     *          The selected value index.
     * @param isSelected
     *          Whether the data is selected.
     * @param cellHasFocus
     *          Whether the data has the focus.
     * @return the component.
     */
    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
    {
      this.setOpaque(true);

      if (isSelected) {
        this.setBackground(list.getSelectionBackground());
        this.setForeground(list.getSelectionForeground());
      }
      else {
        this.setBackground(list.getBackground());
        this.setForeground(list.getForeground());
      }

      if (value instanceof ContainerPortletDescription) {
        ContainerPortletDescription description = (ContainerPortletDescription) value;
        this.setText(description.getName());
      }
      else if (value instanceof SimplePortletDescription) {
        SimplePortletDescription description = (SimplePortletDescription) value;
        this.setText(description.getName());
      }
      else if (value instanceof String) {
        String portletName = (String) value;
        this.setText(portletName);
      }
      else {
        this.setText("");
      }
      return this;
    }

  }



  /**
   * Get the settings from the current selection.
   * 
   * @return the settings.
   */
  @Override
  public PortletInitialSettings getSettings()
  {
    PortletInitialSettings settings = null;
    PortletType portletType = (PortletType) this.comboType.getSelectedItem();
    Object portlet = this.comboPortlet.getSelectedItem();
    PortletDescription portletDescription = null;
    String portletName = null;
    if (portlet instanceof PortletDescription) {
      portletDescription = (PortletDescription) portlet;
      settings = new PortletInitialSettings(portletDescription, portletType);
    }
    else if (portlet instanceof String) {
      portletName = (String) portlet;
      settings = new PortletInitialSettings(portletName, portletType);
    }
    else {
      settings = new PortletInitialSettings(portletDescription, portletType);
    }
    return settings;
  }

}
